import type { ElementSelectors } from '../../lib/abstract'
import type {
  ComponentStyleIdType,
  ECElementEvent,
  ECharts,
  EChartsOption,
  PieChartDataConfig,
} from '../../types/interfaces'
import type { PieChartProps } from './types'
import { UIComponent } from '../../lib/abstract'
import { ComponentStyleId, logger } from '../../types/constants'
import { SYMBOLS } from '../../types/interfaces'
import { styles } from './styles'
import { DEFAULT_PIE_CHART_PROPS } from './types'

export class PieChart extends UIComponent<PieChartProps> {
  id: string = 'pie-chart'
  readonly description: string = '饼图组件'
  readonly styleId: string = ComponentStyleId[this.name]
  private chartInstance: ECharts | null = null
  private resizeObserver: ResizeObserver | null = null

  get name(): ComponentStyleIdType {
    return 'PieChart'
  }

  get className(): string {
    return 'custom-pie-chart'
  }

  constructor(props: PieChartProps) {
    super({
      ...DEFAULT_PIE_CHART_PROPS,
      ...props,
    })

    this.registerStyles()
  }

  ELEMENT_SELECTORS: ElementSelectors = {}

  /**
   * 初始化图表
   * @private
   */
  private initChart(): void {
    if (!this.props.id) {
      logger.error(`[${this.name}] 容器 id 不能为空`)
      return
    }

    const container = document.getElementById(this.props.id)

    if (!container) {
      logger.error(`[${this.name}] 容器 id 为 ${this.props.id} 的元素不存在`)
      return
    }

    this.chartInstance = echarts.init(container)
    this.updateChart()

    // 添加响应式处理
    this.resizeObserver = new ResizeObserver(() => {
      this.chartInstance?.resize()
    })
    this.resizeObserver.observe(container)
  }

  /**
   * 更新图表配置
   * @private
   */
  private updateChart(): void {
    if (!this.chartInstance)
      return

    const { data, options } = this.props

    // 预处理数据，为每个数据项添加自定义属性
    const processedData = data.map((item: any) => ({
      ...item,
      showLabel: item.value > 0,
      label: {
        show: item.value > 0,
      },
      labelLine: {
        show: item.value > 0,
      },
    }))

    const defaultOptions: EChartsOption = {
      tooltip: {
        trigger: 'item',
        formatter: '{a} <br/>{b}: {c} ({d}%)',
      },
      legend: {
        orient: 'vertical',
        right: 0,
        top: 'top',
      },
      series: [{
        name: this.props.title || '数据',
        type: 'pie',
        radius: this.props.radius || ['40%', '70%'],
        center: ['40%', '50%'], // 将饼图向左移动，给图例留出空间
        avoidLabelOverlap: true,
        itemStyle: {
          borderRadius: 10,
          borderColor: '#fff',
          borderWidth: 2,
        },
        label: {
          show: true,
          color: '#1E90FF',
          formatter: (params: any) => {
            return params.data.showLabel ? `${params.name}: ${params.value}\n(${params.percent}%)` : ''
          },
        },
        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: 'rgba(0, 0, 0, 0.5)',
          },
        },
        data: processedData,
        ...this.props.seriesOptions,
      }],
      ...options,
    }

    this.chartInstance.setOption(defaultOptions)
  }

  render(): string {
    const { id, height = '300px', width = '100%' } = this.props

    return this.isEmptyData()
      ? ''
      : `
      <div id="${id}" 
        class="${this.className}" 
        style="height: ${height}; width: ${width};">
      </div>
    `
  }

  bindEvents(): void {
    // 如果数据为空，不绑定事件
    if (this.isEmptyData()) {
      logger.notice(`[${this.name}] ${SYMBOLS.STATUS.WARNING} ${this.props.id} （${this.props.title || '饼图'}） 数据为空，跳过生成图表`)
      return
    }

    setTimeout(() => {
      this.initChart()
      this.handleChartClick()
    }, 0)
  }

  handleChartClick(): void {
    this.chartInstance?.on('click', (params: ECElementEvent) => {
      if (params.componentType === 'series' && params.seriesType === 'pie') {
        // logger.info(`[${this.name}] ${this.props.containerId} 饼图点击事件触发`, params)

        this.props.onClick?.(
          {
            chartId: this.props.id,
            dataIndex: params.dataIndex,
            name: params.name,
            value: params.value,
            seriesName: params.seriesName,
            rawData: params.data,
          },
          params.event,
        )
      }
    })
  }

  /**
   * 刷新图表数据
   */
  refresh(data: any[], options?: EChartsOption): void {
    if (!this.chartInstance) {
      this.initChart()
      return
    }

    const processedData = data.map((item: any) => ({
      ...item,
      showLabel: item.value > 0,
      label: {
        show: item.value > 0,
      },
      labelLine: {
        show: item.value > 0,
      },
    }))

    this.chartInstance.setOption({
      series: [{
        data: processedData,
        ...options?.series,
      }],
      ...options,
    })
  }

  /**
   * 检查是否为空数据
   */
  private isEmptyData(): boolean {
    const { data, renderEmpty } = this.props

    return !renderEmpty && (data.length === 0 || data.every((item: PieChartDataConfig) => item.value === 0))
  }

  getChartInstance(): ECharts | null {
    return this.chartInstance
  }

  getStyles(): string {
    return styles(this.className)
  }

  destroy(): void {
    super.destroy()
  }

  cleanupReferences(): void {
    this.resizeObserver?.disconnect()
    this.resizeObserver = null
    this.chartInstance?.dispose()
    this.chartInstance = null
  }
}
